﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevExpress.Utils;
using DevExpress.XtraScheduler;
using Lamex.Library;

namespace Lamex.mMES.UI
{
    public partial class frmMES_Lab_Schedule : frmBaseChild

    //WINFORM中使用DEV的日程控件《SchedulerControl》实现甘特图效果
    //https://blog.csdn.net/timfeng2009/article/details/81328048?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
    //devexpress15.2 甘特图
    //https://blog.csdn.net/niechaoya/article/details/71194685?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

    //How to: Create a Gantt Chart Application
    //https://documentation.devexpress.com/WindowsForms/10699/Controls-and-Libraries/Scheduler/Examples/Gantt-View/How-to-Create-a-Gantt-Chart-Application


    //https://supportcenter.devexpress.com/ticket/details/t504162/how-to-connect-gantt-view-for-the-xtrascheduler-bound-to-ms-sql-server-database
    {
        #region 自定义结构类型：任务
        struct Task
        {
            /// <summary>
            /// ID
            /// </summary>
            public Guid ID { get; set; }

            /// <summary>
            /// 父ID
            /// </summary>
            public Guid? ParentID { get; set; }

            /// <summary>
            /// 任务名称
            /// </summary>
            public string TaskName { get; set; }
            /// <summary>
            /// 计划开始时间
            /// </summary>
            public DateTime? PlanStart { get; set; }
            /// <summary>
            /// 计划结束时间
            /// </summary>
            public DateTime? PlanEnd { get; set; }
            /// <summary>
            /// 计划开数
            /// </summary>
            public double? PlanDiffDay
            {
                get
                {
                    if (PlanStart.HasValue && PlanEnd.HasValue)
                    {
                        return (PlanEnd.Value - PlanStart.Value).TotalDays;
                    }
                    return null;
                }
            }

            /// <summary>
            /// 完成百分比
            /// </summary>
            public int PercentComplete { get; set; }


            /// <summary>
            /// 前置任务ID
            /// </summary>
            public Guid? BeforeID { get; set; }

            /// <summary>
            /// 依赖方式（开始-结束，结束-开始等）
            /// </summary>
            public AppointmentDependencyType DependencyType { get { return AppointmentDependencyType.FinishToStart; } }

            /// <summary>
            /// 是否全天任务
            /// </summary>
            public bool AllDay { get { return true; } }

            /// <summary>
            /// 排序
            /// </summary>
            public int Sort { get; set; }
        }
        #endregion

        private List<Task> list = new List<Task>();

        public frmMES_Lab_Schedule()
        {
            InitializeComponent();
            //list = CreateList().ToList();
            this.Load += (s, e) =>
            {
                /*资源属性映射*/
                var sourceMap = this.schedulerStorage1.Resources.Mappings;
                sourceMap.Caption = "TaskName";
                sourceMap.Id = "ID";
                sourceMap.ParentId = "ParentID";

                /*依赖关系属性映射*/
                var dependceMap = schedulerStorage1.AppointmentDependencies.Mappings;
                dependceMap.DependentId = "ID";
                dependceMap.ParentId = "BeforeID";
                dependceMap.Type = "DependencyType";

                /*事件属性映射*/
                var appointMentMap = this.schedulerStorage1.Appointments.Mappings;
                appointMentMap.ResourceId = "ID";
                appointMentMap.AppointmentId = "ID";
                appointMentMap.Start = "PlanStart";
                appointMentMap.End = "PlanEnd";
                appointMentMap.Description = "TaskName";
                appointMentMap.AllDay = "AllDay";
                appointMentMap.Subject = "TaskName";
                appointMentMap.PercentComplete = "PercentComplete";

                this.schedulerStorage1.Resources.DataSource = list;
                this.schedulerStorage1.AppointmentDependencies.DataSource = list;
                this.schedulerStorage1.Appointments.DataSource = list;
            };
        }


        /// <summary>
        /// 创建一个任务
        /// </summary>
        private Task Create(Guid? parentID = null, Guid? beforeID = null)
        {
            var now = DateTime.Now;
            var random = new Random(2);
            if (list.Any())
            {
                now = list.Max(u => u.PlanEnd).Value;
            }
            var task = new Task()
            {
                ID = Guid.NewGuid(),
                ParentID = parentID,
                TaskName = "新任务" + (list.Count + 1),
                BeforeID = beforeID,
                PlanStart = now.Date,
                PlanEnd = now.AddDays(random.Next(2, 10)).Date,
                Sort = list.Count + 1,
                PercentComplete = random.Next(100),
            };
            return task;
        }


        private IEnumerable<Task> CreateList()
        {
            var now = DateTime.Now;
            var random = new Random(2);
            for (int i = 0; i < 10; i++)
            {
                var task = new Task()
                {
                    ID = Guid.NewGuid(),
                    TaskName = "新任务" + i.ToString(),
                    PlanStart = now.Date,
                    PlanEnd = now.AddDays(random.Next(2, 10)).Date,
                    Sort = i,
                    PercentComplete = random.Next(100),
                };

                now = task.PlanEnd.Value;
                yield return task;
            }
        }

        /// <summary>
        /// 添加同级任务
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ToolStripMenuItemAdd_Click(object sender, EventArgs e)
        {
            Guid? parentID = null;
            if (resourcesTree1.FocusedNode != null && resourcesTree1.FocusedNode.ParentNode != null)
            {
                parentID = (Guid)resourcesTree1.FocusedNode.ParentNode.GetValue(resourceTreeColumnID);
            }
            list.Add(Create(parentID));
            this.resourcesTree1.RefreshDataSource();
            this.schedulerControl1.RefreshData();
        }

        /// <summary>
        /// 添加子任务
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ToolStripMenuItemAddChildren_Click(object sender, EventArgs e)
        {
            if (resourcesTree1.FocusedNode != null)
            {
                var id = (Guid)resourcesTree1.FocusedNode.GetValue(resourceTreeColumnID);
                list.Add(Create(id));
                this.resourcesTree1.RefreshDataSource();
                this.schedulerControl1.RefreshData();
            }
        }
        /// <summary>
        /// 添加后置任务
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ToolStripMenuItemAddAfter_Click(object sender, EventArgs e)
        {
            if (resourcesTree1.FocusedNode != null)
            {
                Guid? thisId = (Guid)resourcesTree1.FocusedNode.GetValue(resourceTreeColumnID);
                Guid? parentID = null;
                if (resourcesTree1.FocusedNode.ParentNode != null)
                {
                    parentID = (Guid)resourcesTree1.FocusedNode.ParentNode.GetValue(resourceTreeColumnID);
                }
                list.Add(Create(parentID, thisId));
                this.schedulerControl1.RefreshData();
            }

        }

        /// <summary>
        /// 切换焦点，甘特图跟随切换
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void resourcesTree1_FocusedNodeChanged(object sender, DevExpress.XtraTreeList.FocusedNodeChangedEventArgs e)
        {
            if (resourcesTree1.FocusedNode != null)
            {
                var date = (DateTime)resourcesTree1.FocusedNode.GetValue("PlanStart");
                this.schedulerControl1.GoToDate(date);
            }
        }
        /// <summary>
        /// 表格值修改后，刷新甘特图
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void resourcesTree1_CellValueChanged(object sender, DevExpress.XtraTreeList.CellValueChangedEventArgs e)
        {
            var id = (Guid)e.Node.GetValue(resourceTreeColumnID);
            var obj = list.FirstOrDefault(u => u.ID == id);
            var index = list.IndexOf(obj);
            switch (e.Column.FieldName)
            {
                case "TaskName":
                    obj.TaskName = e.Value.ToString();
                    break;
                case "PlanStart":
                    obj.PlanStart = ((DateTime)e.Value).Date;
                    break;
                case "PlanEnd":
                    obj.PlanEnd = ((DateTime)e.Value).Date;
                    break;
                default:
                    var pro = obj.GetType().GetProperty(e.Column.FieldName);
                    pro.SetValue(obj, e.Value, null);
                    break;
            }
            list[index] = obj;
            this.schedulerControl1.RefreshData();
        }

        /// <summary>
        /// 双击后开启单元格编辑效果
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void resourcesTree1_DoubleClick(object sender, EventArgs e)
        {
            resourcesTree1.OptionsBehavior.Editable = true;
            resourcesTree1.ShowEditor();
            resourcesTree1.OptionsBehavior.Editable = false;
        }

    }

}
